import styles from './Search.less';
import React from 'react';
import classNames from 'classnames';
import { Intent, Classes, Tooltip, Icon } from "@blueprintjs/core";
import { ajax_get } from '../../../api/ajax';
import { connect } from 'dva';
import { updateState } from '../../../models/global';
import {replaceAll, unique, uniqueObjectArray} from '../../../utils/util';
import * as turf from '@turf/turf';
import {ToasterWarning} from '../../../components/Toaster';
import SearchSetting from './SearchSetting';
import {flashLayer} from '../../../utils/animate';

function getIcon(type) {
    switch(type) {
        case "roads":
            return "flow-linear";
        case "houses":
            return "home";
        case "buildings":
            return "office";
        case "communities":
            return "calculator";
        default:
            return "map-marker"
    }
}

class SearchPane extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            keyword: '',
            result: [], // geom,名称,搜索,机构编码
            limit: 10,
            showResultPane: false,
            source: null,
            layer: null,
            marker: null,
			settingVisible: false,
			street: true,
			road: true,
            build: true,
            house: true,
            communities: true,
			match: "2"
        }
    }

    // 移除Marker
    removeMarker = () => {
        const {marker} = this.state;
        if(marker) {
            marker.remove();
        }
        this.setState({marker: null});
    }

    // 添加搜索Marker
    addMarker = (item) => {
        if(!item) return;
        const {map} = this.props;
        if(!map) return;
        this.removeMarker();
        var el = document.createElement('div');
        el.className = 'searchMarker';
        el.style.width = '30px';
        el.style.height = '48px';
        el.style.background = 'url("./images/poi_orange.png") center bottom no-repeat';
        el.style.backgroundSize = '100% auto';
        el.setAttribute('title', item['名称'] || item['name']);
        const marker = new atlas.Marker(el, {
            offset: [0, -30]
        }).setLngLat(JSON.parse(item.geom).coordinates).addTo(map);
        this.setState({marker: marker});
    }

    remove = () => {
        this.setState({keyword: '', result: [], showResultPane: false});
        this.removeResultOnMap();
		this.removeBdInfo();
    }

	setting = () => {
		this.setState({settingVisible: true})
	}

	settingClose =() => {
		this.setState({settingVisible: false})
	}

	handleHouseChange = () => {
		this.setState({house: !this.state.house})
	}

	handleRoadChange = () => {
		this.setState({road: !this.state.road})
	}

	handleBuildChange = () => {
		this.setState({build: !this.state.build})
	}

  handleCommunitiesChange = () => {
    this.setState({communities: !this.state.communities})
  }

	handleMatchChange = (event) => {
		this.setState({match: event.target.value})
	}

    /**
     * 在地图中查找
     */
    queryInMap = () => {
        const {atmap, map} = this.props;
        const {keyword} = this.state;
        let features = [];
        if(!atmap || !map || !keyword) return features;
        let sourceIds = atmap.layers.map((layer) => {
            return map.getLayer(layer.id);
        }).filter(layer => layer && layer.source && layer.type === 'symbol').map(layer => layer.source);
        sourceIds = unique(sourceIds);
        sourceIds.forEach((source) => {
            features = features.concat(map.querySourceFeatures(source));
        });
        features = features.filter((feature) => {
            const name = feature && feature.properties && feature.properties['名称'];
            return name && name.indexOf(keyword) >= 0;
        });
        features = uniqueObjectArray(features, 'properties', 'id');
        return features;
    }

    query = (isAddToMap) => {
        const {keyword, limit, showResultPane} = this.state;
        const _keyword = replaceAll(keyword, ' ', '');
        if(!_keyword || _keyword.length <= 1) {
            this.setState({result:[], showResultPane: false});
            if(isAddToMap) {
                // this.removeResultOnMap();
            }
            return;
        };
		// window.local = new BMap.LocalSearch();
		// local.search(keyword);
        const {roadDataset} = this.props;
        const {road, house, build, communities} = this.state;
        const that = this;
        const data = {
            matchtype: this.state.match,
            keyword: _keyword
        };
        let types = [];
        if(house) types.push("houses");
        if(road) types.push("roads");
        if(build) types.push("buildings");
        if(communities) types.push("communities");
        if(types.length > 0) {
            types = types.join(",");
        } else {
            types = null;
        }
        if(types) {
            data.types = types;
        }
        ajax_get({
            // url: `/datasets/search/${roadDataset}/?type=0&field=name&keyword=${_keyword}&limit=${limit}`,
            url: `dm/search/`,
            data
        }).then((res) => {
            if(!res || !res.data) {
                that.setState({result:[]});
            } else {
                let arr = [];
                if(res.data && res.data.length) {
					let bdres = {};
					if(bdRes && bdRes.getResults && bdRes.getResults() &&
					bdRes.getResults().Qq && bdRes.getResults().Qq.length) {
						for(const item of bdRes.getResults().Qq) {
							if(item.business.indexOf("道路") > 0) {
								bdres = item;
								bdres.name = item.business.substr(0,item.business.indexOf("-"));
								break;
							}
						}
					}
                    res.data.map(item => {
                        arr.push({
                            geom: item.geom,
                            gid: item.gid,
                            name: item.name,
                            type: item.type || "",
                            districts: item.districts || "",
							typename: item.typename || "",
							db: bdres.name && bdres.name === item.name &&
								(bdres.district === item.districts || (bdres.district === "南京市" && item.districts === "市本级"))
								? bdres : ""
                        })
                    })
                    that.setState({result: arr});
                }
            }
            that.setState({showResultPane: true});
            // if(isAddToMap) {
            //     setTimeout(() => {
            //         that.addResultToMap();
            //     }, 100);
            // }
        })
    }

	removeBdInfo = () => {
		const {baiduMap} = this.props;
		if(!baiduMap) return;
		baiduMap.clearOverlays();
		this.removeResultOnMap();
		baiduMap.removeEventListener("click", this.removeBdInfo);
		window.baiduMap = baiduMap;
	}

	setPlace = (val) => {
		const {baiduMap} = this.props;
		if(!baiduMap || !val) return;
		this.removeBdInfo();    //清除地图上所有覆盖物
		function myFun(){
			var pp = local.getResults().getPoi(0).point;    //获取第一个智能搜索的结果
			// baiduMap.centerAndZoom(pp, 18);
			// baiduMap.addOverlay(new BMap.Marker(pp));    //添加标注
			var point = new BMap.Point(pp.lng,pp.lat);
			var marker = new BMap.Marker(point);  // 创建标注
			baiduMap.addOverlay(marker);              // 将标注添加到地图中
			var opts = {
			  width : 200,     // 信息窗口宽度
			  height: 50,     // 信息窗口高度
			}
			var infoWindow = new BMap.InfoWindow(val.business, opts);  // 创建信息窗口对象
			baiduMap.openInfoWindow(infoWindow,point);
			marker.addEventListener("click", function(){
				baiduMap.openInfoWindow(infoWindow,point); //开启信息窗口
			});
		}
		var local = new BMap.LocalSearch(baiduMap, { //智能搜索
		  onSearchComplete: myFun
		});
		var myValue = val.province +  val.city +  val.district +  val.street +  val.business;
		local.search(myValue);
		window.myValue = myValue;
		baiduMap.addEventListener("click", this.removeBdInfo);
		map.once("click", this.removeBdInfo);
	}

	componentWillMount() {
		const that = this;
    if(!window.bdRes) {
      window.bdRes = new BMap.Autocomplete(    //建立一个自动完成的对象
      	{
      		"input" : "suggestId",
      		"location": "南京市",
      		"onSearchComplete": (result) => {
      			let bdres = {};
      			if(result.Qq && result.Qq.length) {
      					for(const item of result.Qq) {
      						if(item.business.indexOf("道路") > 0) {
      							bdres = item;
      							bdres.name = item.business.substr(0,item.business.indexOf("-"));
      							break;
      						}
      					}
      				}
      			const {baiduMap} = that.props;
      			if(baiduMap) {
      				setTimeout(() => {
      					let ar = that.state.result;
      					ar.map(item => {
      						if(bdres.name) {
      							item.bd =  bdres.name && bdres.name === item.name &&
      							(bdres.district === item.districts || (bdres.district === "南京市" && item.districts === "市本级")) ?
      							bdres : "";
      						}
      						if(!item.bd) {
      							for(const res of result.Qq) {
      								if(res.business === item.name) {
      									item.bd = res;
      									break;
      								}
      							}
      						}
      					})
      					that.setState({result: ar});
      				},500)
      			}
      		}
      	},
      );
    }
	}

    keypress = (e) => {
        // if(e.which !== 13) return;
        this.query();
    }

    getSourceFeature =(id, name)=>{
        const {atmap, map} = this.props;
        if(!atmap) return null;
        let sourceIds = atmap.layers.map((layer) => {
            return map.getLayer(layer.id);
        }).filter(layer => layer && layer.source && layer.type === 'symbol').map(layer => layer.source);
        sourceIds = unique(sourceIds);
        let features = [];
        sourceIds.forEach((source) => {
            features = features.concat(map.querySourceFeatures(source));
        });
        return features.filter((f) => {
            const props = f.properties;
            return props['id'] === id && props['名称'] === name;
        })[0];
    }

    locate = (item) => {
        if(!item) {
            return;
        }
        if(!item.geom) {
            ToasterWarning({message: `未获取到${item.name}的定位信息，无法定位`});
            return;
        }
        const {map, addFeatureSymbol, addFeatureCircle, setSelectedFeature} = this.props;
        if(!map) return;
        const geom = JSON.parse(item.geom);
		this.setPlace(item.bd)
		// this.removeResultOnMap();
		ajax_get({
			url: `/dm/list/${item.gid}/`,
			data: {type: item.type}
		}).then((res) => {
			if(!res) return;
			let result = res.data;
			if(!result || !result.length) {
				ToasterWarning({message: `未获取到${item.name}的信息`});
				return;
			}
			result  = result[0];
			// 加载属性面板
			setSelectedFeature && setSelectedFeature(result);
		})
        // setSelectedFeature && setSelectedFeature(item);
        const type = geom && geom.type;
        if(type === 'Point') {
//             if(addFeatureSymbol && addFeatureCircle) {
//                 let sourceFeature = null;
//                 if(item.id && item['名称']) {
//                     sourceFeature = this.getSourceFeature(item.id, item['名称']);
//                 }
//                 if(sourceFeature) {
//                     const originSource = map.getSource('searchSource');
//                     if(originSource) {
//                         originSource.setData({type:'FeatureCollection', features: []});
//                     }
//
//                     addFeatureSymbol(sourceFeature);
//                     const isBaseBank = (sourceFeature.properties['机构编码'] && sourceFeature.properties['名称']) || sourceFeature.properties['规划建议'];
//                     if(isBaseBank) {
//                         addFeatureCircle(sourceFeature);
//                     }
//                 } else {
//                     addFeatureSymbol({
//                         type: 'Feature',
//                         geometry:geom,
//                         properties: {},
//                     });
//                 }
//             } else {
//                 this.addMarker(item);
//             }
            map.flyTo({center: geom.coordinates, zoom: 15});

        } else {
            const bbox = turf.bbox(geom);
            const bounds = new atlas.LngLatBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]);
            map.fitBounds(bounds,{
				padding: {top: 150, bottom:150, left: 200, right: 200}
			});
        }
		map.once("moveend", () => {
			this.addResultToMap({geom, gid: item.gid, name: item.name});
		})
		// setTimeout(() => {
		// 	this.addResultToMap({geom, gid: item.gid, name: item.name});
		// },1000)
    }

    removeResultOnMap = () => {
        const {map,sign} = this.props;
        if(map) {
			if(sign) {
				clearInterval(sign);
				cancelAnimationFrame(sign);
			}
            const {marker} = this.state;
            if(marker) marker.remove();
            const layer = map.getLayer('searchLayer1');
            if(layer) {
                map.removeLayer('searchLayer1');
            }
            const layer2 = map.getLayer('searchLayer2');
            if(layer2) {
                map.removeLayer('searchLayer2');
            }
			const layer3 = map.getLayer('dmdz-locate-layer');
			if(layer3) {
			    map.removeLayer('dmdz-locate-layer');
			}
			const layer4 = map.getLayer('atlasdata-ext-dmdz-roads-source-layer');
			if(layer4) {
				map.removeLayer('atlasdata-ext-dmdz-roads-source-layer')
			}
			const layer5 = map.getLayer('atlasdata-ext-dmdz-focus-poi-source');
			if(layer5) {
				map.removeLayer('atlasdata-ext-dmdz-focus-poi-source')
			}
			const layer6 = map.getLayer('dmdz-locate-layer-circle');
			if(layer6) {
				map.removeLayer('dmdz-locate-layer-circle')
			}
            const searchSource = map.getSource('searchSource');
            if(searchSource) {
                // map.removeSource('searchSource');
            }
        }
    }

    addResultToMap = ({gid, name, geom}) => {
        const {map} = this.props;
        this.removeResultOnMap();
        if(map && geom) {
			let feature = map.queryRenderedFeatures(),
				  feature_geo = null;
			feature.map(fea => {
				if(fea.properties.gid === gid && fea.properties.name === name) {
					feature_geo = fea.geometry;
				}
			})
			if(feature_geo) {
				geom = feature_geo;
			}
            let type = geom.type;
            const sourceId = 'atlasdata-ext-searchSource';
            const source = map.getSource(sourceId);
            if(!source) {
                map.addSource(sourceId, {
                    type: 'geojson',
                    data: {
                        type: "FeatureCollection",
                        features: [{
                            type: 'Feature',
                            geometry: geom,
                            properties: {
                                gid,
                            }
                        }]
                    }
                });
            } else {
                source.setData({
                    type: "FeatureCollection",
                    features: [{
                        type: 'Feature',
                        geometry: geom,
                        properties: {
                            gid,
                        }
                    }]
                });
            }
            if(type.indexOf('Point') >= 0) {
                map.addLayer({
                    id: 'searchLayer1',
                    source: sourceId,
                    'type': 'circle',
                    paint: {
                    	'circle-color': '#08F',
                    	'circle-opacity': 0.7,
                    	'circle-radius': 10,
                    },
                    metadata: {
                        name: "搜索图层"
                    }
                });
				let sign = flashLayer({
				    map: map,
				    layer: 'searchLayer1',
				    type: 'paint',
				    property: 'circle-color',
					on: '#08F',
					off: '#000',
				    interval: 200,
				    // timer: 3000,
				    end: () => {
				        map.setLayoutProperty('searchLayer1', 'visibility', 'none');
				    }
				});
				updateState({sign})
            } else {
                if(type.indexOf("Polygon") >= 0) {
                    map.addLayer({
                        id: 'searchLayer1',
                        source: sourceId,
                        'type': 'fill',
                        paint: {
                          'fill-color': '#00F',
                          'fill-opacity': 1,
                          'fill-outline-color': '#4A90FA',
                        },
                        metadata: {
                            name: "搜索图层"
                        }
                    });
					let sign = flashLayer({
					    map: map,
					    layer: 'searchLayer1',
					    type: 'paint',
					    property: 'fill-color',
						on: '#00F',
						off: '#000',
					    interval: 200,
					    // timer: 3000,
					    end: () => {
					        map.setLayoutProperty('searchLayer1', 'visibility', 'none');
					    }
					});
					updateState({sign})
                }
                if(type.indexOf("Line") >= 0) {
                    map.addLayer({
                        id: 'searchLayer2',
                        source: sourceId,
                        'type': 'line',
                        paint: {
                            'line-color': '#08F',
                            'line-opacity': 0.7,
                            'line-width': 10
                        },
                        metadata: {
                            name: "搜索图层"
                        }
                    });
					let sign = flashLayer({
					    map: map,
					    layer: 'searchLayer2',
					    type: 'paint',
					    property: 'line-color',
						on: '#08F',
						off: '#000',
					    interval: 200,
					    // timer: 3000,
					    end: () => {
					        map.setLayoutProperty('searchLayer2', 'visibility', 'none');
					    }
					});
					updateState({sign})
                }
            }
        }
    }

    render() {
        const {keyword, result, showResultPane} = this.state;

        return (
          <div className={styles.searchWrap}>
			  {/* <span className={styles.searchSpan}>搜索:</span> */}
              <input id="suggestId" type="text" placeholder="请输入关键词" maxLength="40"
              value={keyword}
              onChange={(e) => { this.setState({keyword: e.target.value});setTimeout(() => { this.query(); }, 200); }} />
              <button className={styles.btnRemove} onClick={this.remove} title='清空搜索结果'></button>
			  <button className={styles.btnSetting} onClick={this.setting} title='高级设置'></button>
              <button className={styles.btnQuery} onClick={() => {this.query(true)}} title='搜索'></button>
              <div className={styles.result} style={{display: showResultPane ? 'block' : 'none' }}>
                <ul>
                    {showResultPane && result && result.map((item, index) => {
                        return <li className={item.bd ? styles["bd-res"] : ""} key={index} onClick={() => {this.locate(item)}}>
                            {item.type !== "communities" ?
                            <Icon icon={getIcon(item.type)} /> : <span className={styles.communities}></span>}
                            &nbsp;&nbsp;
                            {item['名称']||item['name'] + ` - `}
                            {item['typename'] + `    ` + item["districts"]}
                        </li>
                    })}
                    {showResultPane && (!result||!result.length) && <div>
                        共找到0个搜索结果， 您可以检查输入是否正确或者输入其它词
                        </div>}
                </ul>
              </div>
              <SearchSetting
                handleClose={this.settingClose}
                isOpen={this.state.settingVisible}
                street={this.state.street}
                road={this.state.road}
                build={this.state.build}
                communities={this.state.communities}
                house={this.state.house}
                match={this.state.match}
                handleHouseChange={this.handleHouseChange}
                handleRoadChange={this.handleRoadChange}
                handleBuildChange={this.handleBuildChange}
                handleMatchChange={this.handleMatchChange}
               />
          </div>
        );
    }

}

function mapStateToProps(state) {
    return {
		sign: state.map.sign,
		baiduMap: state.map.baiduMap,
		map: state.map.map,
    };
}

export default connect(mapStateToProps)(SearchPane);
